// pages/group/index.ts
import { formatMessageDate } from "../../utils/format";
import { formatTimestamp } from "../../utils/index";
import { groupLeave, rewriteImMessage } from "../../utils/api";
import tran from "../../utils/language";
import dayjs from "dayjs";
import { handleImUserData } from "../../utils/index.js";
Page({
    /**
     * 页面的初始数据
     */
    data: {
        _t: tran._t("group"),
        _tBase: tran._t("base"),
        showEventPopup: false,
        info: {
            groupId: "",
            joinedGroupTime: "",
        },
        targetUserInfo: {
            groupId: "",
            avatarurl: "",
        },
        loginInfo: {
            userId: "",
        },
        userId: "",
        messageData: [] as any[],
        textareaValue: "",
        scrollTop: 0,
        userInfoList: [
            {
                userId: "",
                avatarurl: "",
                nickname: "",
            },
        ],
        cursor: -1,
        loading: false,
        scrolltoupperFlag: false,
        msgFlag: true,
        currentTimestamp: Math.floor(Date.now()), // 当前时间戳（秒）
        contentHeight: 0, // 内容高度
        confirmPopup: {
            showPopup: false,
            topTitle: tran._t("base").topTitleTip,
            midText: tran._t("group").leaveGroupText,
            confirmText: tran._t("base").confirmText,
            closeText: tran._t("base").closeBtnText,
        },
    },
    /**
     * 生命周期函数--监听页面加载
     */
    onLoad(options: any) {
        const loginInfo = wx.getStorageSync("userInfo");
        this.setData({
            loginInfo,
        });
        if (options && options.info) {
            const info = JSON.parse(options.info); // 群组的信息
            this.setData(
                {
                    info: info,
                    targetUserInfo: info,
                },
                () => {
                    this.getHistoryList();
                }
            );
        }
        this.takeOverMsg();
    },
    /**
     * 确认框确认按钮
     */
    confirmFn() {
        const { targetUserInfo } = this.data;
        const that = this;
        const params = {
            groupTypeId: targetUserInfo.groupTypeId,
            groupId: targetUserInfo.groupId,
        };
        groupLeave(params).then((res: any) => {
            that.setData(
                {
                    showEventPopup: false,
                },
                () => {
                    wx.switchTab({
                        url: "/pages/home/index",
                    });
                }
            );
        });
        this.closeFn();
    },
    /**
     * 关闭确认框
     */
    closeFn() {
        const { confirmPopup } = this.data;
        confirmPopup.showPopup = false;
        this.setData({
            confirmPopup,
        });
    },
    /**
     * 将scroll-view中的内容滚动到最底部
     */
    setScrollToBottom() {
        const query = wx.createSelectorQuery();
        // 获取类名为message-box
        query
            .select(".message-box")
            .boundingClientRect((rect) => {
                this.setData({
                    scrollTop: rect.height
                        ? rect.height * 1 + 100000
                        : 1000000000, // 设置 scroll-top 为内容高度，使其滚动到底部
                });
            })
            .exec();
    },
    /**
     * 滚动条滚到顶部触发
     */
    scrolltoupper(e: any) {
        const { cursor } = this.data;
        if (cursor != -1) {
            this.setData({
                scrolltoupperFlag: true,
            });
            this.getHistoryList();
        }
    },
    groupMore() {
        this.setData({
            showEventPopup: true,
        });
    },
    audioChange1(e: any) {
        const info = e.detail;
        const { targetUserInfo } = this.data;
        const that = this;
        let option = {
            // 消息类型。
            type: "audio",
            body: {
                //文件 URL。
                url: info.url,
                //文件类型。
                type: "audio",
                //文件名。
                filename: "filename",
                // 音频文件时长，单位为秒。
                length: Math.ceil(info.duration / 1000),
            },
            // 消息接收方：单聊为对方用户 ID，群聊和聊天室分别为群组 ID 和聊天室 ID。
            to: targetUserInfo.groupId,
            // 会话类型：单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`，默认为单聊。
            chatType: "groupChat",
        };
        let msg = wx.WebIM.message.create(option);
        // 调用 `send` 方法发送该文本消息。
        wx.conn
            .send(msg)
            .then((res: any) => {
                // 调用获取历史消息
                // this.getHistoryList()
                that.updateMessageList(res.message);
            })
            .catch((e) => {
                console.log("Send message fail", e);
            });
    },
    // 发送语音消息
    audioChange(e: any) {
        const info = e.detail;
        const { targetUserInfo } = this.data;
        // 处理临时的发送中的消息
        // this.loadingMsg(info, "audio");
        let option = {
            // 消息类型。
            type: "custom",
            // 消息接收方：单聊为对方用户 ID，群聊和聊天室分别为群组 ID 和聊天室 ID。
            to: targetUserInfo.groupId,
            // 会话类型：单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`，默认为单聊。
            chatType: "groupChat",
            customEvent: "customEvent",
            // key 和 value 只支持字符串类型，否则客户端无法解析。
            customExts: {
                //文件 URL。
                url: info.url,
                //文件类型。
                type: "audio",
                //文件名。
                filename: "filename",
                // 音频文件时长，单位为秒。
                length:
                    Math.ceil(info.duration / 1000) > 60
                        ? 60
                        : Math.ceil(info.duration / 1000).toString(),
            },
            // 消息扩展字段，不能设置为空，即设置为 "ext:null" 会出错。
            ext: { isPlay: false, isPlayMe: false } as any,
        };
        let msg = wx.WebIM.message.create(option);
        msg.sendStatus = "loading";
        msg.from = this.data.loginInfo.userId;
        msg.createTime = dayjs().format("HH:mm:ss");
        msg.createDate = dayjs().format("YYYY-MM-DD HH:mm:ss");
        msg.sender = true;
        this.setData({ messageData: [...this.data.messageData, msg] }, () => {
            // 滚动到底部
            this.setScrollToBottom();
        });
        // 调用 `send` 方法发送该文本消息。
        wx.conn
            .send(msg)
            .then((res: any) => {
                // 发送成功后清楚消息输入框内容
                this.setData({
                    textareaValue: "",
                });
                // 调用获取历史消息
                // this.getHistoryList();
            })
            .catch((e: any) => {
                console.log(e, "错误");
            });
    },
    // 播放语音
    sendCMDMessage(obj: any) {
        console.log(obj);
        const { loginInfo } = this.data;
        if (
            obj.detail.from === loginInfo.userId ||
            obj.detail.ext[loginInfo.userId]
        ) {
            return;
        }
        let params = {
            msgId: obj.detail.id,
            newMsgType: obj.detail.type,
            newTxtMsg: "",
            newCustomExts: obj.detail.customExts,
            newExt: { ...obj.detail.ext } as any,
        };
        params.newExt[loginInfo.userId] = true;
        rewriteImMessage(params).then((res: any) => {
            const i = this.data.messageData.findIndex(
                (v) => v.id === obj.detail.id
            );
            if (i !== -1) {
                this.data.messageData[i].ext[loginInfo.userId] = true;
                this.setData({
                    messageData: [...this.data.messageData],
                });
            }
        });
    },
    /**
     * 跳转到群成员页面
     * @param e
     */
    goGroup() {
        const { info } = this.data;
        wx.navigateTo({
            url: `/pages/group/members/index?info=${JSON.stringify(info)}`,
        });
    },
    /**
     * 视频改变事件
     * @param e
     */
    videoChange(e: any) {
        if (e.detail) {
            // this.sendPrivateVideo(e.detail)
            this.sendPrivateUrlVideo(e.detail);
        }
    },
    /**
     * 上传图片完后触发此回调
     * @param e
     */
    imgChange(e: any) {
        if (e.detail) {
            // this.sendPrivateImg(e.detail)
            this.sendPrivateUrlImg(e.detail);
        }
    },
    /**
     * 输入框改变事件(或者点击了发送触发)
     */
    textareaChange(e: any) {
        this.setData(
            {
                textareaValue: e.detail,
            },
            () => {
                this.sendTextMessage();
            }
        );
    },
    /**
     * 获取用户属性
     * @param arr
     */
    getUserInfo(arr: any) {
        const that = this;
        const userIds: any = [];
        arr.length > 0 &&
            arr.map((item: any) => {
                userIds.push(item.from);
            });
        let userList: any = JSON.parse(JSON.stringify(userIds));
        // avatarurl
        wx.conn.fetchUserInfoById(userList).then((res: any) => {
            const userInfoList = handleImUserData(userList, res.data);
            this.setData(
                {
                    userInfoList: JSON.parse(JSON.stringify(userInfoList)),
                },
                () => {
                    that.handleMessage(arr);
                }
            );
        });
    },
    /**
     * 获取历史消息
     */
    getHistoryList() {
        const { info, loginInfo, targetUserInfo, cursor } = this.data;
        const that = this;
        let options = {
            targetId: info.groupId, // 单聊为对端用户 ID，群组聊天为群组 ID。
            chatType: "groupChat", // 会话类型：单聊、群组聊天和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`。
            pageSize: 50, // 每次获取的消息数量，取值范围为 [1,50]，默认值为 `50`。最大50条
            cursor: -1, // 查询的起始消息 ID。若该参数设置为 `-1`、`null` 或空字符串，从最新消息开始。
            searchDirection: "up", // 消息搜索方向。`up` 表示按消息时间戳递减的方向获取，即先获取最新消息；`down` 表示按消息时间戳递增的方向获取，即先获取最老的消息。
            searchOptions: {
                // from: loginInfo.userId, // 消息发送方的用户 ID。该参数仅用于群组聊天。
                // msgTypes: ['txt'], // 要获取的消息类型的数组。若不传值，会获取所有类型的消息。
                msgTypes: [], // 要获取的消息类型的数组。若不传值，会获取所有类型的消息。
                startTime: dayjs(info.joinedGroupTime).valueOf(), // 查询的起始时间戳，单位为毫秒。
                endTime: dayjs().valueOf(), // 查询的结束时间戳，单位为毫秒。
            } as any,
        };
        console.log("====================================");
        console.log(options);
        console.log("====================================");
        wx.conn.getHistoryMessages(options).then((res: any) => {
            if (res.messages.length > 0) {
                // const newMessages = this.data.messageData.concat(res.messages);
                // const newMessages = [...res.messages, ...this.data.messageData]
                // const newMessages = [...this.data.messageData, ...res.messages, ...messagesHisList]
                // const newMessages = [...res.messages, ...this.data.messageData]
                const list = res.messages.reverse();
                const newMessages = [...list, ...this.data.messageData];
                that.getUserInfo(newMessages);
                console.log(newMessages, "9");
                let msgFlag = that.data.cursor == res.cursor ? true : false;

                // 因为，如果没有数据的话，返回的是字符串类型的undefined，所以得这么判断
                that.setData({
                    cursor:
                        res.cursor && res.cursor != "undefined"
                            ? res.cursor
                            : -1, // 更新游标
                    msgFlag: msgFlag,
                });
            }
        });
    },

    /**
     * 接收消息监听
     */
    takeOverMsg() {
        const that = this;
        const { info } = this.data;
        wx.conn.addEventHandler("eventName", {
            onReceivedMessage: (message) => {
                // 消息到达服务器
                console.log(message);
                const i = this.data.messageData.findIndex(
                    (v) => v.id === message.id
                );
                if (i !== -1) {
                    this.data.messageData[i].sendStatus = "success";
                    this.data.messageData[i].id = message.mid;
                    this.setData({
                        messageData: [...this.data.messageData],
                    });
                }
            },
            // 收到文本消息
            onTextMessage: function (message: any) {
                console.log(message, 66666666666);
                // 判断如果这条消息不是来自当前点击的用户，就不往下执行
                if (message.to !== info.groupId) return;
                const { messageData } = that.data;
                messageData.push(message);
                that.handleMessage(messageData);
            },
            // 当前用户收到语音消息。
            onCustomMessage: function (message: any) {
                console.log("audio", message);
                // 判断如果这条消息不是来自当前点击的用户，就不往下执行
                if (message.to !== info.groupId) return;
                const { messageData } = that.data;
                // 语音文件在服务器的地址。message.url
                messageData.push(message);
                that.handleMessage(messageData);
            },
            // 收到图片消息
            onImageMessage: function (message: any) {
                // 判断如果这条消息不是来自当前点击的用户，就不往下执行
                if (message.to !== info.groupId) return;
                const { messageData } = that.data;
                messageData.push(message);
                that.handleMessage(messageData);
            },
            // 收到视频消息
            onVideoMessage: function (message: any) {
                // 判断如果这条消息不是来自当前点击的用户，就不往下执行
                if (message.to !== info.groupId) return;
                const { messageData } = that.data;
                messageData.push(message);
                // 视频文件在服务器的地址。
                console.log(message.url);
                // 视频首帧缩略图文件在服务器的地址。
                console.log(message.thumb);
                that.handleMessage(messageData);
            },
        });
    },
    /**
     * 处理 IM 返回的的消息数据
     * @param arr
     */
    handleMessage(arr: any) {
        const that = this;
        const currentDate = dayjs().format("YYYY-MM-DD");
        const { targetUserInfo, loginInfo, scrolltoupperFlag, info } =
            this.data;
        arr.length > 0 &&
            arr.map((item: any, index: any) => {
                // 过滤出用户头像
                if (this.data.userInfoList) {
                    const userArr = this.data.userInfoList.filter(
                        (everyOne: any) => everyOne.userId == item.from
                    );
                    const userObj =
                        userArr.length > 0 ? userArr[0] : { avatarurl: "" };
                    item.avatar =
                        userObj.avatarurl ||
                        "https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg";
                }
                const date = dayjs(item.time).format("YYYY-MM-DD HH:mm:ss");
                item.createTime = dayjs(item.time).format("HH:mm:ss");
                item.createDate =
                    dayjs(item.time).format("YYYY-MM-DD") == currentDate
                        ? item.createTime
                        : dayjs(item.time).format("YYYY-MM-DD HH:mm:ss");
                item.sender = item.from == loginInfo.userId ? true : false; // 发送者的userId如果是本地登录用户的id，那么这条消息就是我是发送者
                item.message = item.msg;
                item.timeText = dayjs(item.time).format("mm:ss");
                item.currentRead = false; // 音频当前是否播放的判断标识
                // item.avatar = targetUserInfo.avatarurl || 'https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg'
                item.msgTime = formatTimestamp(item.time);
                const showTime =
                    index === 0 ||
                    that.shouldShowTime(arr[index - 1].time, item.time);
                // 以为第一条消息默认都要展示时间
                item.showTime = index === 0 ? true : showTime;
            });
        that.setData(
            {
                messageData: arr,
            },
            () => {
                that.setScrollToBottom();
            }
        );
        // if (msgFlag) {
        //   const history = wx.getStorageSync(targetUserInfo.userId) || [];
        //   list1 = [...history, ...arr]
        // }
        // const list2 = that.saveChatHistory(targetUserInfo.userId, list1)
        // wx.setStorageSync(targetUserInfo.userId, arr);
        wx.setStorageSync(info.groupId, arr);
        that.setData(
            {
                messageData: arr,
            },
            () => {
                // 说明往上滑动了，加载了数据
                if (!scrolltoupperFlag) {
                    that.setScrollToBottom();
                }
            }
        );
    },
    /**
     * 数组去重
     * @param tempArr
     */
    arrayUnique(tempArr: any) {
        let newArr = [];
        for (let i = 0; i < tempArr.length; i++) {
            const list = newArr.filter((item) => item.id == tempArr[i].id);
            if (list.length == 0) {
                newArr.push(tempArr[i]);
            }
        }
        return newArr;
    },
    /**
     * 处理发送消息
     * 更新当前消息列表，两个触发位置（消息监听、发送方调用发送）
     * @param data
     */
    updateMessageList(data: any) {
        let message = {};
        if (data?.detail) {
            message = {
                ...data.detail,
            };
        } else {
            message = {
                ...data,
            };
        }
        const arr1 = [message];
        const arr = [...this.data.messageData, ...arr1];
        this.handleMessage(arr);
    },
    /**
     * 保存聊天记录
     * @param conversationId
     * @param messages
     */
    saveChatHistory(conversationId: string, messages: any[]) {
        const history = wx.getStorageSync(conversationId) || [];
        const list1 = [...history, ...messages];
        const arr = this.arrayUnique(list1);
        // console.log(arr, '数组数组数组');
        wx.setStorageSync(conversationId, arr);
        return arr;
    },
    shouldShowTime(lastTimestamp: any, currentTimestamp: any) {
        // 获取当前时间和上一条消息时间的差值（单位：秒）
        const diff = currentTimestamp - lastTimestamp;
        // 假设如果消息间隔小于 1 小时（3600秒），就不显示时间
        // return diff >= 3600000;  // 1小时
        return diff >= 1800000; // 半小时
    },
    /**
     * 发送文本消息
     */
    sendTextMessage() {
        const { textareaValue, targetUserInfo, loginInfo } = this.data;
        const that = this;
        let option = {
            // 消息类型。
            type: "txt",
            // 消息内容。
            msg: textareaValue,
            from: loginInfo.userId,
            // 消息接收方：单聊为对方用户 ID，群聊和聊天室分别为群组 ID 和聊天室 ID。
            to: targetUserInfo.groupId,
            // 会话类型：单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`，默认为单聊。
            chatType: "groupChat",
        };
        let msg = wx.WebIM.message.create(option);
        msg.sendStatus = "loading";
        msg.createTime = dayjs().format("HH:mm:ss");
        msg.createDate = dayjs().format("YYYY-MM-DD HH:mm:ss");
        msg.sender = true;
        this.setData({ messageData: [...this.data.messageData, msg] }, () => {
            // 滚动到底部
            this.setScrollToBottom();
        });
        // 调用 `send` 方法发送该文本消息。
        wx.conn
            .send(msg)
            .then((res: any) => {
                // 发送成功后清除消息输入框内容
                that.setData({
                    textareaValue: "",
                });
                // that.updateMessageList(res.message);
                // 调用获取历史消息
                // this.getHistoryList()
            })
            .catch((e) => {
                // 清除消息输入框内容
                this.setData({
                    textareaValue: "",
                });
                let msg = e.message == "blocked" ? "黑名单" : e.message;
                // type == 603  拉黑
                this.setData({
                    blackNameFlag: e.message == "blocked" ? true : false,
                });
            });
    },
    /**
     * 发送视频消息（视频已上传到我们服务器）
     */
    sendPrivateUrlVideo(info: any) {
        console.log(info, "这里的url");
        const { targetUserInfo } = this.data;
        const that = this;
        let option = {
            chatType: "groupChat",
            // 消息类型。
            type: info.fileType || "video",
            url: info.url,
            filename: "filename",
            body: {
                url: info.url,
                video: info.fileType || "video",
                filename: "filename",
            },
            // 消息接收方：单聊为对方用户 ID，群聊和聊天室分别为群组 ID 和聊天室 ID。
            to: targetUserInfo.groupId,
        };
        // 创建一条图片消息。
        let msg = wx.WebIM.message.create(option);
        msg.sendStatus = "loading";
        msg.from = this.data.loginInfo.userId;
        msg.sender = true;
        msg.url = info.url;
        this.setData({ messageData: [...this.data.messageData, msg] }, () => {
            // 滚动到底部
            this.setScrollToBottom();
        });
        // 调用 `send` 方法发送该文本消息。
        wx.conn
            .send(msg)
            .then((res: any) => {
                // that.updateMessageList(res.message);
                // that.getHistoryList();
            })
            .catch((e: any) => {
                // 清除消息输入框内容
                let msg = e.message == "blocked" ? "黑名单" : e.message;
                // type == 603  拉黑
                this.setData({
                    blackNameFlag: e.message == "blocked" ? true : false,
                });
            });
    },
    /**
     * 发送图片消息（图片已上传到我们服务器）
     */
    sendPrivateUrlImg(info: any) {
        const { targetUserInfo } = this.data;
        const that = this;
        let option = {
            chatType: "groupChat",
            // 消息类型。
            type: info.fileType || "img",
            url: info.url,
            body: {
                url: info.url,
            },
            // 消息接收方：单聊为对方用户 ID，群聊和聊天室分别为群组 ID 和聊天室 ID。
            to: targetUserInfo.groupId,
        };
        // 创建一条图片消息。
        let msg = wx.WebIM.message.create(option);
        msg.sendStatus = "loading";
        msg.from = this.data.loginInfo.userId;
        msg.sender = true;
        msg.url = info.url;
        this.setData({ messageData: [...this.data.messageData, msg] }, () => {
            // 滚动到底部
            this.setScrollToBottom();
        });
        // 调用 `send` 方法发送该文本消息。
        wx.conn
            .send(msg)
            .then((res: any) => {
                // that.updateMessageList(res.message);
                // that.getHistoryList()
            })
            .catch((e: any) => {
                // 清除消息输入框内容
                let msg = e.message == "blocked" ? "黑名单" : e.message;
                // type == 603  拉黑
                this.setData({
                    blackNameFlag: e.message == "blocked" ? true : false,
                });
            });
    },
    closePopup() {
        this.setData({ showEventPopup: false });
    },
    leaveGroup() {
        const { targetUserInfo, confirmPopup } = this.data;
        confirmPopup.showPopup = true;
        this.setData({
            confirmPopup,
        });
        const that = this;
        // const leave = e.target.dataset.leave
        // leave && console.log('离开群组');
        // const customPopup = this.selectComponent('#event-popup');
        // customPopup && customPopup.hidePopup()
        // 这里
        // wx.showModal({
        //   title: '提示',
        //   content: '确定要退出该群组?',
        //   success(res) {
        //     if (res.confirm) {
        //       const params = {
        //         groupTypeId: targetUserInfo.groupTypeId,
        //         groupId: targetUserInfo.groupId
        //       }
        //       groupLeave(params).then((res: any) => {
        //         that.setData({
        //           showEventPopup: false
        //         }, () => {
        //           wx.switchTab({
        //             url: '/pages/home/index'
        //           })
        //         })
        //       })
        //     } else if (res.cancel) {
        //       console.log('用户点击取消')
        //     }
        //   }
        // })
    },
    onClosePopup(e: baseEvent) {
        // const leave = e.target.dataset.leave
        // leave && console.log('离开群组');
        // const customPopup = this.selectComponent('#event-popup');
        // customPopup && customPopup.hidePopup()
        this.setData({
            showEventPopup: false,
        });
    },
    seeMoreTap() {
        const { info } = this.data;
        wx.navigateTo({
            url: `/pages/profile/hotDetail/index?info=${JSON.stringify(info)}`,
        });
    },
    onBack() {
        wx.navigateBack();
    },
    formatDate(data: messageType[]) {
        const newArr: messageType[] = [];
        let lastdate = "";
        data.forEach((i: messageType) => {
            const { date, createTime, createDate } = formatMessageDate(
                i.timestamp
            );
            newArr.push({
                ...i,
                createTime,
                createDate: lastdate !== createDate ? date : "",
            });
            lastdate = createDate;
        });
        this.setData({ messageData: newArr });
    },

    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady() {},

    /**
     * 生命周期函数--监听页面显示
     */
    onShow() {},

    /**
     * 生命周期函数--监听页面隐藏
     */
    onHide() {},

    /**
     * 生命周期函数--监听页面卸载
     */
    onUnload() {},

    /**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh() {},

    /**
     * 页面上拉触底事件的处理函数
     */
    onReachBottom() {},

    /**
     * 用户点击右上角分享
     */
    onShareAppMessage() {},
});
